/* Copyright   1991 Gustavus Adolphus College.  All rights reserved.
 *
 * Schematik was developed by Gustavus Adolphus College (GAC) with
 * support from NeXT Computer, Inc.  Permission to copy this software,
 * to redistribute it, and to use it for any purpose is granted,
 * subject to the following restrictions and understandings.
 *
 * 1. Any copy made of this software must include this copyright
 * notice in full.
 *
 * 2. Users of this software agree to make their best efforts (a) to
 * return to the GAC Mathematics and Computer Science Department any
 * improvements or extensions that they make, so that these may be
 * included in future releases; and (b) to inform GAC of noteworthy
 * uses of this software.
 *
 * 3. All materials developed as a consequence of the use of this
 * software shall duly acknowledge such use, in accordance with the
 * usual standards of acknowledging credit in academic research.
 *
 * 4. GAC makes no express or implied warranty or representation of
 * any kind with respect to this software, including any warranty
 * that the operation of this software will be error-free.  ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR
 * PURPOSE IS HEREBY DISCLAIMED.  GAC is under no obligation to
 * provide any services, by way of maintenance, update, or otherwise.
 *
 * 5. In conjunction with products arising from the use of this
 * material, there shall be no use of the name of Gustavus Adolphus
 * College nor of any adaptation thereof in any advertising,
 * promotional, or sales literature without prior written consent
 * from GAC in each case.
 */

#import "FindAgent.h"
#import "../defines.h"
#import DocText_h
#import DocWin_h
#import Main_h
#import PrefAgent_h
#import <appkit/Button.h>
#import <appkit/Form.h>
#import <appkit/Text.h>
#import <mach.h>
#import <string.h>
extern void NXBeep(void);

#define NIBFILE		"Find.nib"
#define FINDZONENAME	"FindAgnt"
static id theAgent=nil;

@implementation FindAgent

+ new
{
DEBUG_FUNC1(DEBUGLEVEL);
    if (theAgent==nil)
      {
        NXZone *tempZone;

        tempZone = NXCreateZone(vm_page_size, vm_page_size, YES);
        DEBUG_ASSERT(tempZone!=NULL)
        theAgent = self = [super allocFromZone:tempZone];
	agentZone = tempZone;
	NXNameZone(agentZone, FINDZONENAME);
      }
    return theAgent;
}

- activateAgent:sender
{
DEBUG_FUNC1(DEBUGLEVEL);
    if (!findPanel)
      {
        findPanel = LoadNIB(NIBFILE, theAgent, agentZone);
        DEBUG_ASSERT(findPanel!=nil)
        [findPanel useOptimizedDrawing:YES];
        EnableMenuItem(FindMenuCell3(MENU_EDIT, MENU_EDIT_FIND, MENU_EDIT_FIND_FindNext));
        EnableMenuItem(FindMenuCell3(MENU_EDIT, MENU_EDIT_FIND, MENU_EDIT_FIND_FindPrevious));
      }
    [findText selectTextAt:0];
    [findPanel makeKeyAndOrderFront:self];
    return self;
}

- findForward:sender
{
DEBUG_FUNC1(DEBUGLEVEL);
    [msgText setStringValue:NULL];
    [findText selectTextAt:0];
    if (*[findText stringValueAt:0])
      if (![[[NXApp mainWindow] textView] stringSearch:[findText stringValueAt:0] forAgent:self direction:FINDFORWARD ignoreCase:[ignoreCase state] wholeWord:[wholeWord state] inSel:NO])
        {
          NXBeep();
          [msgText setStringValue:NOTFOUNDMESSAGE];
          return self;
        }
    [[[NXApp mainWindow] textView] scrollSelToVisible];
    return self;
}

- findBackward:sender
{
DEBUG_FUNC1(DEBUGLEVEL);
    [msgText setStringValue:NULL];
    [findText selectTextAt:0];
    if (*[findText stringValueAt:0])
      if (![[[NXApp mainWindow] textView] stringSearch:[findText stringValueAt:0] forAgent:self direction:FINDBACKWARD ignoreCase:[ignoreCase state] wholeWord:[wholeWord state] inSel:NO])
        {
          NXBeep();
          [msgText setStringValue:NOTFOUNDMESSAGE];
          return self;
        }
    [[[NXApp mainWindow] textView] scrollSelToVisible];
    return self;
}

- replace:sender
{
DEBUG_FUNC1(DEBUGLEVEL);
    [[[NXApp mainWindow] textView] replaceSel:[findText stringValueAt:1]];
    [[NXApp mainWindow] setDocEdited:YES];
    return self;
}

- replaceAll:sender
{
    const char *message=REPLACEDMESSAGE;
    char buffer[strlen(message)+16];
    int count=0;
    id text=[[NXApp mainWindow] textView];

DEBUG_FUNC1(DEBUGLEVEL);
    [msgText setStringValue:NULL];
    [findText selectTextAt:0];
    if (*[findText stringValueAt:0])
      {
        NXSelPt dummy,bend,start;
        [[NXApp mainWindow] disableFlushWindow];
        [text saveSelectionState];
        if (![scopeMatrix selectedRow])
          [text selectAll:nil];
        [text getSel:&dummy :&bend];
        while ([text stringSearch:[findText stringValueAt:0] forAgent:self direction:FINDFORWARD ignoreCase:[ignoreCase state] wholeWord:[wholeWord state] inSel:YES])
          {
            [self replace:nil];
            count++;
            [text getSel:&start :&dummy];
            [text setSel:start.cp :bend.cp];
          }
        DEBUG_ASSERT(![text stringSearch:[findText stringValueAt:0] forAgent:self direction:FINDFORWARD ignoreCase:[ignoreCase state] wholeWord:[wholeWord state] inSel:[scopeMatrix selectedRow]])
        [text restoreSelectionState];
        [[[NXApp mainWindow] reenableFlushWindow] flushWindow];
        sprintf(buffer, message, count);
        [msgText setStringValue:buffer];
      }
    return self;
}

- replaceAndFind:sender
{
DEBUG_FUNC1(DEBUGLEVEL);
    return [[self replace:nil] findForward:nil];
}

@end

@implementation FindAgent (Delegate)

- textDidEnd:sender endChar:(unsigned short)theChar
{
DEBUG_FUNC1(DEBUGLEVEL);
    if (theChar==NX_RETURN)
      [findPanel close];
    return self;
}

@end
